import axios from 'axios';
import qs from 'qs';
const ajax = axios.create({
    timeout: 20000,
    headers: {
        'X-Requested-With': 'XMLHttpRequest',
        'Content-Type':"application/x-www-form-urlencoded"
    },
    baseURL:"http://127.0.0.1:8888",
    withCredentials:true
})
// axios.defaults.baseURL = "http://127.0.0.1:8888";
// axios.defaults.headers['Content-Type'] = "application/x-www-form-urlencoded";
// axios.defaults.transformRequest = data => qs.stringify(data);
// axios.defaults.timeout = 0;
// axios.defaults.withCredentials = true;
ajax.install = function (Vue) {
    Vue.prototype.$json = ajax.$json
    Vue.prototype.$jsonSubmit = ajax.$jsonSubmit
    Vue.prototype.$form = ajax.$form
    Vue.prototype.$formGet = ajax.$formGet
    Vue.prototype.$formSubmit = ajax.$formSubmit
    Vue.config.errorHandler = function (err, vm, info) {
        handleError(err, info)
    }
}
ajax.interceptors.request.use(config => {
    // 真实项目中，我们一般会在登录成功后，把从服务器获取的TOKEN信息存储到本地，以后再发送请求的时候，一般都把TOKEN带上（自定义请求头携带）
    let token = localStorage.getItem('token');
    token && (config.headers['Authorization'] = token);
    return config;
});

ajax.interceptors.response.use(response => {
    return response.data;
}, reason => {
    // 从服务器没有获取数据（网络层失败）
    let response = null;
    if (reason) {
        // 起码服务器有响应，只不过状态码是4/5开头的
        response = reason.response;
        switch (response.status) {
            case 401:
                // 一般情况下都是未登录
                break;
            case 403:
                // 一般情况下是TOKEN过期
                break;
            case 404:
                // 地址不存在
                break;
        }
    } else {
        if (!window.navigator.onLine) {
            alert('和抱歉，网络连接已经断开，请联网后再试~~');
        }
    }
    return Promise.reject(response);
});
function showLoading (text) {
    console.log('弹出框')
}
function hideLoading(){
    console.log('关闭弹出框')
}
// 正在请求中的URL
const requestingUrl = new Set()
let canRepeat = false
function request (param) {
    const url = param.url
    let params = param.params
    const contentType = param.contentType
    const layer = param.layer
    const method = param.method || 'post'
    if (layer) {
        const layerText = param.layerText || '提交中'
        showLoading(layerText)
    }
    const ajaxPromise = new Promise((resolve, reject) => {
        const paramsStr = qs.stringify(params)
        // 校验重复请求
        const requestItem = url + '?' + paramsStr
        if (!canRepeat && requestingUrl.has(requestItem)) {
            console.error('请勿重复请求URL：' + url)
            reject({ errMsg: '请勿重复请求' })
        }
        canRepeat && (canRepeat = false)
        requestingUrl.add(requestItem)

        if (contentType === 'application/x-www-form-urlencoded') {
            params = paramsStr
        }
        ajax({
            url: url,
            data: params,
            method: method
        }, {
            headers: {
                'Content-Type': contentType
            }
        }).then(response => {
            requestingUrl.delete(requestItem)
            if (layer) {
                hideLoading()
            }
            const retcode = response.data.retcode
            // 0000操作成功
            if (retcode === '0000') {
                resolve(response.data)
            } else if (retcode === '303' || retcode === '399') { // 登录跳转
                // 停止其他请求
                cancelAllAjax()
                // 清除cookie
                cookie.remove('baqi_jwt')
                cookie.remove('roleType')
                // 跳转登录去
                router.push('/login?fromUrl=' + location.hash.replace('#', ''))
            } else { // 抛错，进入下面的onRejected || function(err){}逻辑
                reject(response.data) // 若没有then函数，这句话会console.error Uncaught (in promise)

            }
        }, err => {

        })
    })
    return ajaxPromise
}
ajax.$json = function (api, param = {}) {
    return request({
        url: api,
        params: param,
        contentType: 'application/json'
    })
}

ajax.$jsonSubmit = function (url, layerText, param) {
    if (param === undefined) {
        [layerText, param] = [param, layerText]
    }
    return request({
        url: url,
        params: param,
        contentType: 'application/json',
        layer: true,
        layerText: layerText
    })
}

ajax.$form = function (url, param) {
    return request({
        url: url,
        params: param,
        contentType: 'application/x-www-form-urlencoded'
    })
}

ajax.$formGet = function (url) {
    return request({
        url: url,
        method: 'get',
        contentType: 'application/x-www-form-urlencoded'
    })
}

ajax.$formSubmit = function (api, layerText, param) {
    if (param === undefined) {
        [layerText, param] = [param, layerText]
    }
    return request({
        url: api,
        params: param,
        contentType: 'application/x-www-form-urlencoded',
        layer: true,
        layerText: layerText
    })
}

export default ajax;